/*
 * @Author: 李石
 * @Date: 2024-04-18 17:58:16
 * @LastEditors: lishi
 * @LastEditTime: 2024-05-22 18:59:31
 * @Description: 
 * Copyright (c) 2024 by ${lishi0105@163.com}, All Rights Reserved. 
 */
#ifndef _SMAPRT_QUEUE_HPP_
#define _SMAPRT_QUEUE_HPP_

#include <deque>
#include <memory>
#include <mutex>

template <typename T> 
class  SmartQueue
{
public:
    explicit SmartQueue(size_t cache_size = 10) : 
        cache_size_(cache_size)
    {
    }

    virtual ~SmartQueue( )
    {
        Clear();
    }

    void PushBack(const std::shared_ptr<T>& element) 
    {
        std::lock_guard<std::mutex> lock(mtx_mp);
        if (data_cache.size() >= cache_size_) {
            data_cache.pop_front();
        }
        data_cache.push_back(element);
    }

    std::shared_ptr<T> PopFront() 
    {
        std::lock_guard<std::mutex> lock(mtx_mp);
        if(data_cache.empty()){
            return nullptr;
        }
        auto tmp = data_cache.front();
        data_cache.pop_front();
        return tmp;
    }

    size_t Size ()
    {
        std::lock_guard<std::mutex> lock(mtx_mp);
        return data_cache.size();
    }

    void Clear()
    {
        std::lock_guard<std::mutex> lock(mtx_mp);
        data_cache.clear();
    }
private:
    std::deque<std::shared_ptr<T>> data_cache;
    size_t      cache_size_;
    std::mutex    mtx_mp;
};

#endif //_BASE_CACHE_QUEUE_HPP_